﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace MyLibrary
{
    /// <summary>
    /// 泛型参数类型(单一参数)
    /// </summary>
    /// <typeparam name="ParamType">事件参数</typeparam>
    public class GenericEventArgs<ParamType> : EventArgs
    {
        ParamType _param;
        public ParamType Param
        {
            get { return _param; }
        }
        /// <summary>
        /// 泛型事件参数(单一参数)
        /// </summary>
        /// <param name="param">事件参数类型</param>
        public GenericEventArgs(ParamType param)
        {
            this._param = param;
        }
    }

    /// <summary>
    /// 泛型参数类型(两个参数)
    /// </summary>
    /// <typeparam name="ParamType1">第一参数</typeparam>
    /// <typeparam name="ParamType2">第二参数</typeparam>
    public class GenericEventArgs<ParamType1, ParamType2> : EventArgs
    {
        ParamType1 _param1;
        ParamType2 _param2;
        public ParamType1 Param1
        {
            get { return _param1; }
        }

        public ParamType2 Param2
        {
            get { return _param2; }
        }

        /// <summary>
        /// 泛型参数类型(单一参数)
        /// </summary>
        /// <param name="param1">第一参数</param>
        /// <param name="param2">第二参数</param>
        public GenericEventArgs(ParamType1 param1, ParamType2 param2)
        {
            this._param1 = param1;
            this._param2 = param2;
        }
    }

    /// <summary>
    /// 泛型参数类型(三个参数)
    /// </summary>
    /// <typeparam name="ParamType1">第一参数</typeparam>
    /// <typeparam name="ParamType2">第二参数</typeparam>
    public class GenericEventArgs<ParamType1, ParamType2, ParamType3> : EventArgs
    {
        ParamType1 _param1;
        ParamType2 _param2;
        ParamType3 _param3;
        public ParamType1 Param1
        {
            get { return _param1; }
        }

        public ParamType2 Param2
        {
            get { return _param2; }
        }

        public ParamType3 Param3
        {
            get { return _param3; }
        }

        /// <summary>
        /// 泛型参数类型(单一参数)
        /// </summary>
        /// <param name="param1">第一参数</param>
        /// <param name="param2">第二参数</param>
        public GenericEventArgs(ParamType1 param1, ParamType2 param2, ParamType3 param3)
        {
            this._param1 = param1;
            this._param2 = param2;
            this._param3 = param3;
        }
    }

    /// <summary>
    /// 泛型单例
    /// </summary>
    /// <typeparam name="T">实现单例的类</typeparam>
    public abstract class Singleton<T>
    {
        private static object _syncObj = new object();
        private static T _instance;

        public static T Instance
        {
            get
            {
                if (_instance == null)
                {
                    Monitor.Enter(_syncObj);
                    if (_instance == null)
                    {
                        try
                        {
                            _instance = Activator.CreateInstance<T>();
                        }
                        finally
                        {
                            Monitor.Exit(_syncObj);
                        }
                    }
                }
                return _instance;
            }
            set
            {
                Monitor.Enter(_syncObj);
                try
                {
                    _instance = value;
                }
                finally
                {
                    Monitor.Exit(_syncObj);
                }
            }
        }
    }

    /// <summary>
    /// 所有可以"启动"的类的统一接口
    /// </summary>
    public interface IStartable
    {
        void Start();
        void Stop();

        bool IsRun { get; }
        bool CanRun { get; }

        event EventHandler<GenericEventArgs<IStartable>> OnStartableStatueChange;
    }

    /// <summary>
    /// "可启动"对象基类
    /// </summary>
    public abstract class StartableBaseClass : IStartable
    {
        protected bool _isRun;
        protected bool _canRun;

        protected abstract void OnStart();
        protected abstract void OnStop();

        #region IStartable Members

        /// <summary>
        /// 启动对象
        /// </summary>
        public void Start()
        {
            if (this._isRun)
                throw new RuntimeException("对象已处于运行状态");
            OnStart();
            this._isRun = true;
            if (this.OnStartableStatueChange != null)
                this.OnStartableStatueChange(this, new GenericEventArgs<IStartable>(this));
        }

        public void Stop()
        {
            if (!_isRun)
                return;

            OnStop();
            _isRun = false;
            if (this.OnStartableStatueChange != null)
                this.OnStartableStatueChange(this, new GenericEventArgs<IStartable>(this));
        }

        public bool IsRun
        {
            get { throw new NotImplementedException(); }
        }

        public bool CanRun
        {
            get { throw new NotImplementedException(); }
        }

        public event EventHandler<GenericEventArgs<IStartable>> OnStartableStatueChange;

        #endregion
    }

    /// <summary>
    /// 可释放,可启动类的抽象类
    /// </summary>
    public abstract class DisposeableAndStartableBase : StartableBaseClass, IDisposable
    {
        private bool _disposed = false;

        /// <summary>
        /// 防止对象被重复释放
        /// </summary>
        protected bool Disposed
        {
            get 
            {
                lock (this)
                    return _disposed;
            }
        }

        ~DisposeableAndStartableBase()
        {

        }

        /// <summary>
        /// 该方法在对象被释放的时候被调用,重写该方法,以释放类使用的资源
        /// </summary>
        /// <param name="disposeByUser">是否释放托管资源(true 释放 false 不释放)</param>
        protected virtual void Free(bool disposeByUser)
        {
           
        }

        /// <summary>
        /// 是否对象资源
        /// </summary>
        public void Dispose()
        {
            lock (this)
            {
                if (_disposed == false)
                {
                    Free(true);
                    _disposed = true;
                    GC.SuppressFinalize(this);
                }
            }
        }
    }

    public abstract class DisposeableBase : IDisposable
    {
        private bool _disposed = false;

        protected virtual void Free(bool disposedByUser)
        {
        }

        public void Dispose()
        {
            lock (this)
            {
                if (this._disposed == false)
                {
                    Free(true);
                    _disposed = true;
                    GC.SuppressFinalize(this);
                }
            }
        }

        protected bool Disposed
        {
            get 
            {
                lock (this)
                    return _disposed;
            }
        }

        ~DisposeableBase()
        {
            Free(false);
        }
    }
}
